/**
 * State class handles a specific state for both player1 and player2
 * @author jens & Jeppe
 */
public class State 
{
	public int spaceLeftY[] = new int[Common.XSIZE];
	public VectorPosHandling VPS_Player1 = new VectorPosHandling();
	public VectorPosHandling VPS_Player2 = new VectorPosHandling();
	public int pos = 0;
	private int lastActionPlayer1 = 0;
	private int lastActionPlayer2 = 0;	
	/**
	 * Add a coin to the board
	 * @param x
	 * @param player
	 */
	public boolean insertElement(int x, int player)
	{		
		int yPos = 0;
		if(spaceLeftY[x]>=0 && spaceLeftY[x]<Common.YSIZE)
			yPos = spaceLeftY[x]++;		
		else
			// failed, there is no room in this position
			return false;

		if(yPos>=0)
		{
			if(player==1)
			{
				VPS_Player1.addVectorPos(new VectorPos(x, yPos));
				lastActionPlayer1 = x;
			}
			else
			{
				VPS_Player2.addVectorPos(new VectorPos(x, yPos));
				lastActionPlayer2 = x;
			}
		}
		// otherwise return true if we didnt fail to insert..
		return true;
	}
	/**
	 * Returns the space position left on the specific column
	 * @param x
	 * @return
	 */
	public int getYpos(int x)
	{
		return spaceLeftY[x]; 
	}
	/**
	 * Returns the last action(position) of a player
	 * @param Player
	 * @return
	 */
	public int getLastAction(int playerID)
	{
		if(playerID==Common.PLAYER1)
			return lastActionPlayer1;
		else
			return lastActionPlayer2;
	}
	/**
	 * Searchs the board for a Diagonal endmove for the computer. If there is
	 * one, the method returns the x position of the endmove.
	 * 
	 * @param playerID
	 * @return
	 */
	public int endMovePositionDiagonal(int playerID)
	{
		VectorPos lastAction;
		if(playerID==Common.PLAYER1 && VPS_Player1.getLongestXY()==Common.endMoveSize)
		{
			lastAction = VPS_Player1.getMissingXYPosition();

			if(lastAction != null && lastAction.xPos > 0)
			{
				if(!VPS_Player1.checkPosition(lastAction)&&!VPS_Player2.checkPosition(lastAction))
				{
					return lastAction.xPos;
				}		
			}
		}
		else
			if(playerID==Common.PLAYER2 && VPS_Player2.getLongestX()==Common.endMoveSize)
			{
				lastAction = VPS_Player2.getMissingXYPosition();
				if(lastAction != null && lastAction.xPos > 0)
				{
					if(!VPS_Player1.checkPosition(lastAction)&&!VPS_Player2.checkPosition(lastAction))
					{
						return lastAction.xPos;
					}		
				}
			}			
		return Common.NOVALUE;
	}
	/**
	 * Searchs the board for missing coin in the diagonal list. If there is
	 * one, the method returns the column position of the endmove.
	 * 
	 * @param playerID
	 * @return
	 */
	public int endMoveMissingDiagonal(int playerID)
	{
		if(playerID==Common.PLAYER1)
		{
			VectorPos miss =  VPS_Player1.getMissingXYPosition();
			if(miss.xPos != Common.NOVALUE)
			{
				if(!VPS_Player2.checkPosition(miss)&&!VPS_Player1.checkPosition(miss))
					return miss.xPos;
			}
		}
		else
			if(playerID==Common.PLAYER2)
			{
				VectorPos miss =  VPS_Player2.getMissingXYPosition();
				if(miss.xPos != Common.NOVALUE)
				{
					if(!VPS_Player2.checkPosition(miss)&&!VPS_Player1.checkPosition(miss))
						return miss.xPos;
				}	
			}
		// no value was found
		return Common.NOVALUE;
	}
	/**
	 * Searchs the board for missing coin in a Horizontal list of connected coins. 
	 * If there is one, the method returns the column position of the endmove.
	 * 
	 * @param playerID
	 * @return
	 */
	public int endMoveMissingHorizontal(int playerID)
	{
		if(playerID==Common.PLAYER1)
		{
			VectorPos miss =  VPS_Player1.findMissingXCord();
			if(miss.xPos != Common.NOVALUE)
			{
				if(!VPS_Player2.checkPosition(miss))
					return miss.xPos;
			}
		}
		else
			if(playerID==Common.PLAYER2)
			{
				VectorPos miss =  VPS_Player2.findMissingXCord();
				if(miss.xPos != Common.NOVALUE)
				{
					if(!VPS_Player1.checkPosition(miss))
						return miss.xPos;
				}		
			}
		// no value was found
		return Common.NOVALUE;
	}
	/**
	 * Find a possible endmove, if we have 3 horizontal connected coins
	 * @param PlayerID
	 * @return
	 */
	public int endMovePositionHorizontal(int PlayerID)
	{
		VectorPos lastAction;
		if(PlayerID==Common.PLAYER1 && VPS_Player1.getLongestX()==Common.endMoveSize)
		{
			
			lastAction = VPS_Player1.getLongestXFreeCoordinate(VPS_Player2, Common.endMoveSize);
			Common.debug(" endMovePositionHorizontall:"+lastAction.xPos+" "+lastAction.yPos);
			return lastAction.xPos;
		}
		else
			if(PlayerID==Common.PLAYER2 && VPS_Player2.getLongestX()==Common.endMoveSize)
			{
				lastAction = VPS_Player2.getLongestXFreeCoordinate(VPS_Player1, Common.endMoveSize);
				Common.debug(" endMovePositionHorizontall:"+lastAction.xPos+" "+lastAction.yPos);
				return lastAction.xPos;
			}			
		// if we fail anyway
		return Common.NOVALUE;
	}	
	/**
	 * Find a possible endmove, if we have 3 vertical connected
	 * @return
	 */
	public int endMovePositionVertical(int PlayerID)
	{
		VectorPos lastAction;
		if(PlayerID==Common.PLAYER1 && VPS_Player1.getLongestY()==Common.endMoveSize)
		{
			lastAction = VPS_Player1.getLongestYFreeCoordinate(VPS_Player2, Common.endMoveSize);
			Common.debug(" endMovePositionVertical:"+lastAction.xPos+" "+lastAction.yPos);
			return lastAction.xPos;
		}
		else
			if(PlayerID==Common.PLAYER2 && VPS_Player2.getLongestY()==Common.endMoveSize)
			{
				lastAction = VPS_Player2.getLongestYFreeCoordinate(VPS_Player1, Common.endMoveSize);
				Common.debug(" endMovePositionVertical:"+lastAction.xPos+" "+lastAction.yPos);
				return lastAction.xPos;
			}			
		// if we fail anyway
		return Common.NOVALUE;
	}
	/**
	 * Calculate the utility of the current board
	 * @return
	 */
	public int utility()
	{
		int largeX = VPS_Player1.getLongestX();
		int largeY = VPS_Player1.getLongestY();
		int largeXY = VPS_Player1.getLongestXY();
		int maxValue = Math.max(largeX, largeY);
		maxValue = Math.max(maxValue, largeXY);

		largeX = VPS_Player2.getLongestX();
		largeY = VPS_Player2.getLongestY();
		largeXY = VPS_Player2.getLongestXY();
		int minValue = Math.max(largeX, largeY);
		minValue = -1*Math.max(minValue, largeXY);

		// return the difference between max and min
		return (maxValue+minValue);
	}	
	/**
	 * Copy board for next iteration 
	 * @return
	 */
	public State copyBoard()
	{
		// create temporary state
		State newState = new State();
		// copy the list of space left
		for(int sl=0; sl<Common.XSIZE; sl++)
			newState.spaceLeftY[sl] = this.spaceLeftY[sl];
		// copy the two vector lists
		newState.VPS_Player1 = this.VPS_Player1.copyVH();
		newState.VPS_Player2 = this.VPS_Player2.copyVH();		
		// return a pointer to the copied board
		return newState;
	}
	/**
	 * end of class
	 */
}